import wx
import wx.lib.mixins.listctrl  as  listmix
from bisect import bisect

########################################################################
class EditableListCtrl(wx.ListCtrl, listmix.TextEditMixin):
    ''' TextEditMixin allows any column to be edited. '''

    #----------------------------------------------------------------------
    def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,
                 size=wx.DefaultSize, style=0, name=''):
        """Constructor"""
        wx.ListCtrl.__init__(self, parent, ID, pos, size, style, name=name)
        listmix.TextEditMixin.__init__(self)
        self.flag = True
        self.UnEditCols = [0]
        self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginLabelEdit)
        # self.Unbind(wx.EVT_LEFT_DOWN)
    # 第一列无法编辑
    def OnBeginLabelEdit(self, event):
        if event.GetColumn() in self.UnEditCols:
            event.Veto()
        else:
            event.Skip()

    def OnLeftDown(self, evt=None):
        # isopen作用是用鼠标无法关闭输入框
        super().OnLeftDown(evt)

        self.col_locs = [0]
        loc = 0
        for n in range(self.GetColumnCount()):
            loc = loc + self.GetColumnWidth(n)
            self.col_locs.append(loc)

        x,y = evt.GetPosition()
        col = bisect(self.col_locs, x+self.GetScrollPos(wx.HORIZONTAL)) - 1
        
        if col == 0:
            evt.Skip()

    def OpenEditor(self, col, row):
        # isopen作用是用鼠标无法关闭输入框
        if self.flag:
            super().OpenEditor(col, row)

    
    def CloseEditor(self, evt=None):
        super().CloseEditor(evt)
        

########################################################################
if __name__ == "__main__":
    class MyPanel(wx.Panel):
        """"""

        #----------------------------------------------------------------------
        def __init__(self, parent):
            """Constructor"""
            wx.Panel.__init__(self, parent)

            rows = [("", "Taurus", "1996", "Blue"),
                    ("Nissan", "370Z", "2010", "Green"),
                    ("Porche", "911", "2009", "Red")
                    ]
            self.list_ctrl = EditableListCtrl(self, style=wx.LC_REPORT)

            self.list_ctrl.InsertColumn(0, "Make")
            self.list_ctrl.InsertColumn(1, "Model")
            self.list_ctrl.InsertColumn(2, "Year")
            self.list_ctrl.InsertColumn(3, "Color")

            index = 0
            for row in rows:
                self.list_ctrl.InsertItem(index, row[0])
                self.list_ctrl.SetItem(index, 1, row[1])
                self.list_ctrl.SetItem(index, 2, row[2])
                self.list_ctrl.SetItem(index, 3, row[3])
                index += 1

            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
            self.SetSizer(sizer)


    ########################################################################
    class MyFrame(wx.Frame):
        """"""

        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, None, wx.ID_ANY, "Editable List Control")
            panel = MyPanel(self)
            self.Show()

#----------------------------------------------------------------------

    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()